// Describe:
package core

import (
	"encoding/json"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
	"net"
	"wormhole/pkg/event"
	"wormhole/pkg/udp"
	"wormhole/utils"
)

func (s holeServer) ListenUdp() error {
	//创建数据通信socket
	udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:"+viper.GetString("core.port"))
	if err != nil {
		log.Err(err).Send()
		return err
	}
	conn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		log.Err(err).Send()
		return err
	}
	go func() {
		<-s.Ctx.Done()
		_ = conn.Close()

	}()
	log.Info().Msg("udp server standby!")
	// 监听消息
	for {
		// 获取消息
		buf := make([]byte, 1024)
		n, _, err := conn.ReadFromUDP(buf) //接收客户端发送过来的数据，填充到切片buf中。
		if err != nil {
			return err
		}
		// 解析消息
		udpMessage := new(udp.UdpMessage)
		err = json.Unmarshal(buf[:n], udpMessage)
		if err != nil {
			log.Err(err).Send()
			return err
		}
		ripple := udpMessage.Ripple
		nr := utils.DeepCopyRipple(ripple)
		// 过滤自身消息
		if ripple.Ip == viper.GetString("core.ip") {
			log.Debug().Msg("udp server accept self message")
			continue
		}
		if zerolog.GlobalLevel() < zerolog.InfoLevel {
			utils.Println(udpMessage)
		}
		svc := GetHoleServer()
		// 处理事件
		switch ripple.Event {
		case event.OfflineEvent:
			svc.EventAdd(udpMessage.Ripple)
		case event.RespondEvent:
			svc.EventAdd(udpMessage.Ripple)
		case event.RepeatEvent:
			log.Warn().Str("name", udpMessage.Ripple.Name).Msg("当前网络有重名,建议修改名称")
		case event.BroadcastEvent:
			{
				// 检查名称重复性
				device := svc.GetDeviceByName(ripple.Name)
				if device != nil && device.Key.Ripple.Ip != ripple.Ip {
					//与已知设备冲突
					log.Warn().Msgf("检测到[%v]与[%v]有重名: [%v]", device.Key.Ripple.Ip, ripple.Ip, ripple.Name)
					nr.Event = event.RepeatEvent
					_ = udp.Dimple(nr)
				} else {
					// 加入在线列表
					nr.Event = event.RespondEvent
					_ = udp.Dimple(nr)
					svc.EventAdd(ripple)
				}
			}
		default:
			log.Warn().Str("event", ripple.Event).Msg("遇到未知upd事件类型")
		}
	}
}
